package com.loe.ktui.custom

import android.content.Context
import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.text.method.DigitsKeyListener
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import com.loe.ktui.*
import com.loe.ktui.util.KtColor
import com.loe.ktui.util.KtDecimalInputFilter
import kotlinx.android.synthetic.main.kt_view_form_edit.view.*
import java.util.*

open class UiFormEditView(id: String? = null) : UiFrameLayout(id)
{
    override var width: Any? = MATCH_PARENT

    var isInfo: Boolean? = null
    var title: CharSequence? = null
    var notNull: Boolean? = null
    var text: CharSequence? = null
    var unit: CharSequence? = null
    var hint: CharSequence? = null
    var formGravity: Int? = null
    var inputType: Int? = null
    var minLine: Int? = null
    var maxLen: Int? = null
    var maxLine: Int? = null
    var limitNumber: Int = -1
    var limitDecimal: Int = -1
    var filter: String? = null
    var textSize: Any? = 15
    var titleSize: Any? = null
    var textColor: Int? = null
    var titleColor: Int? = null
    var unitColor: Int? = null
    var titleLeft: Any? = null
    var titleLen: Any? = null
    var tailLen: Any? = null

    var onText: (KtFormEditView.(s: String) -> Unit)? = null
    fun onText(onText: KtFormEditView.(s: String) -> Unit)
    {
        this.onText = onText
    }

    fun initUI(context: Context, view: KtFormEditView)
    {
        super.initUI(context, view)

        isInfo?.let { view.isInfo = it }
        title?.let { view.title = it }
        notNull?.let { view.notNull = it }
        text?.let { view.text = it }
        unit?.let { view.unit = it }
        view.hint = hint ?: (if (isInfo == true) "" else "请输入")
        formGravity?.let { view.formGravity = it }
        inputType?.let { view.inputType = it }
        minLine?.let { view.minLine = it }
        maxLen?.let { view.maxLen = it }
        maxLine?.let { view.maxLine = it }
        view.setLimit(limitNumber, limitDecimal)
        filter?.let { view.setFilter(it) }
        textSize?.let { view.setTextSizePx(it.distFloat) }
        titleSize?.let { view.setTitleSizePx(it.distFloat) }
        titleColor?.let { view.titleColor = it }
        unitColor?.let { view.unitColor = it }
        textColor?.let { view.textColor = it }
        titleLeft?.let { view.titleLeft = it.distFloat }
        titleLen?.let { view.titleLen = it.distFloat }
        tailLen?.let { view.tailLen = it.distFloat }

        onText?.let { onText -> view.setTextListener { view.onText(it) } }
    }

    override fun createView(context: Context, parent: ViewGroup?): KtFormEditView
    {
        return KtFormEditView(context).also()
        {
            initUI(context, it)
            addToParent(parent, it)
        }
    }
}

fun Any.ui_FormEditView(id: String? = null, block: (UiFormEditView.() -> Unit)? = null): UiFormEditView
{
    val ui = UiFormEditView(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

/** 表单编辑View */
open class KtFormEditView : KtFrameLayout
{
    constructor(context: Context) : super(context)
    {
        onCreate(null)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        onCreate(attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        onCreate(attrs)
    }

    private var maxLenFilter: InputFilter? = null
    private var limitFilter: InputFilter? = null

    private fun onCreate(attrs: AttributeSet?)
    {
        val root = inflate(context, R.layout.kt_view_form_edit, null)
        addView(root, MATCH_PARENT, MATCH_PARENT)

        if (attrs != null)
        {
            val typedArray = context.obtainStyledAttributes(attrs, R.styleable.KtFormEditView)

            // isInfo
            isInfo = typedArray.getBoolean(R.styleable.KtFormEditView_kt_form_isInfo, false)
            // title
            title = typedArray.getString(R.styleable.KtFormEditView_kt_form_title) ?: ""
            // notNull
            notNull = typedArray.getBoolean(R.styleable.KtFormEditView_kt_form_notNull, false)
            // text
            text = typedArray.getString(R.styleable.KtFormEditView_kt_form_text) ?: ""
            // unit
            unit = typedArray.getString(R.styleable.KtFormEditView_kt_form_unit) ?: ""
            // hint
            hint = typedArray.getString(R.styleable.KtFormEditView_kt_form_hint) ?: (if (isInfo) "" else "请输入")

            // formGravity
            formGravity = typedArray.getInt(R.styleable.KtFormEditView_kt_form_gravity, Gravity.LEFT)

            // inputType
            when (typedArray.getInt(R.styleable.KtFormEditView_kt_form_inputType, 0))
            {
                1 -> editText.inputType = UiEdit.INPUT_PASSWORD
                2 -> editText.inputType = UiEdit.INPUT_NUMBER
                3 -> editText.inputType = UiEdit.INPUT_DECIMAL
                4 -> editText.inputType = UiEdit.INPUT_TEXT_CODE
                else -> editText.inputType = UiEdit.INPUT_TEXT
            }

            // min
            minLine = typedArray.getInt(R.styleable.KtFormEditView_kt_form_minLine, 1)
            // max
            maxLen = typedArray.getInt(R.styleable.KtFormEditView_kt_form_maxLen, Int.MAX_VALUE)
            maxLine = typedArray.getInt(R.styleable.KtFormEditView_kt_form_maxLine, Int.MAX_VALUE)
            // limit
            setLimit(typedArray.getInt(R.styleable.KtFormEditView_kt_form_limitNumber, -1), typedArray.getInt(R.styleable.KtFormEditView_kt_form_limitDecimal, -1))
            // filter
            setFilter(typedArray.getString(R.styleable.KtFormEditView_kt_form_filter))
            // size
            textSize = dp(typedArray.getDimension(R.styleable.KtFormEditView_kt_form_textSize, ktPx(15).toFloat()))
            titleSize = dp(typedArray.getDimension(R.styleable.KtFormEditView_kt_form_titleSize, ktPx(15).toFloat()))
            // title_color
            titleColor = typedArray.getColor(R.styleable.KtFormEditView_kt_form_titleColor, KtColor.grayDeep)
            // unit_color
            unitColor = typedArray.getColor(R.styleable.KtFormEditView_kt_form_unitColor, KtColor.grayDeep)
            // textColor
            textColor = typedArray.getColor(R.styleable.KtFormEditView_kt_form_textColor, KtColor.text)
            // titleLeft
            titleLeft = typedArray.getDimension(R.styleable.KtFormEditView_kt_form_titleLeft, ktPx(15).toFloat())
            // titleLen
            titleLen = typedArray.getDimension(R.styleable.KtFormEditView_kt_form_titleLen, ktPx(110).toFloat())
            // tailLen
            tailLen = typedArray.getDimension(R.styleable.KtFormEditView_kt_form_tailLen, ktPx(15).toFloat())

            typedArray.recycle()
        }

        if (minimumHeight > 0)
        {
            root.minimumHeight = minimumHeight
        }
    }

    var inputType
        get() = editText.inputType
        set(value)
        {
            editText.inputType = value
        }

    var isInfo = false
        set(value)
        {
            field = value
            editText.isEnabled = !value
            if (value)
            {
                editText.hint = ""
            }
        }

    var notNull = true
        set(value)
        {
            field = value
            textNotNull.visibility = if (value && title.isNotEmpty()) VISIBLE else INVISIBLE
        }

    var title: CharSequence
        get() = textTitle.text
        set(value)
        {
            textTitle.text = value
            notNull = notNull
        }

    var text: CharSequence
        get() = editText.text.trim()
        set(value)
        {
            editText.setText(value)
        }

    var code = ""

    var unit: CharSequence
        get() = textUnit.text
        set(value)
        {
            textUnit.isVisible = value.isNotEmpty()
            textUnit.text = value
        }

    var hint: CharSequence
        get() = editText.hint
        set(value)
        {
            editText.hint = value
        }

    var formGravity = Gravity.LEFT
        set(value)
        {
            field = value
            editText.gravity = value
            editText.isClear = value == Gravity.LEFT
        }

    val string get() = editText.text.trim().toString()

    val stringOrHint get() = editText.text.trim().toString().ifEmpty { hint.toString() }

    var maxLen = Int.MAX_VALUE
        set(value)
        {
            field = value
            maxLenFilter = InputFilter.LengthFilter(value)
            resetFilters()
        }

    var maxLine = Int.MAX_VALUE
        set(value)
        {
            field = value
            editText.isSingleLine = value == 1
            editText.maxLines = value
        }

    var minLine = Int.MAX_VALUE
        set(value)
        {
            field = value
            editText.minLines = value
        }

    fun setLimit(limitNumber: Int, limitDecimal: Int)
    {
        var number = limitNumber
        var decimal = limitDecimal
        if (number < 0 && decimal < 0)
        {
            return
        }
        if (number <= 0)
        {
            number = 16
        }
        if (decimal <= 0)
        {
            decimal = 2
        }
        limitFilter = KtDecimalInputFilter(number, decimal)
        resetFilters()
    }

    fun setFilter(s: String?)
    {
        if (s != null)
        {
            editText.keyListener = DigitsKeyListener.getInstance(s)
        }
    }

    var titleSize = 0f
        set(value)
        {
            field = value
            textTitle.textSize = titleSize
        }

    var textSize = 0f
        set(value)
        {
            field = value
            textTitle.textSize = textSize
            editText.textSize = textSize
            textUnit.textSize = textSize
        }

    var textColor = KtColor.text
        set(value)
        {
            field = value
            editText.setTextColor(value)
        }

    var titleColor = KtColor.grayDeep
        set(value)
        {
            field = value
            textTitle.setTextColor(value)
        }

    var unitColor = KtColor.grayDeep
        set(value)
        {
            field = value
            textUnit.setTextColor(value)
        }

    var titleLeft = 0f
        set(value)
        {
            field = value
            textTitle.marginLeftPx = value.toInt()
        }

    var titleLen = 0f
        set(value)
        {
            field = value
            textTitle.maxWidth = (value - ktPx(35)).toInt()
            editText.setPadding(value.toInt(), ktPx(15), tailLen.toInt(), ktPx(15))
        }

    var tailLen = 0f
        set(value)
        {
            field = value
            editText.setPadding(titleLen.toInt(), ktPx(15), value.toInt(), ktPx(15))
        }

    fun setTitleSizePx(px: Float)
    {
        textTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)
    }

    fun setTextSizePx(px: Float)
    {
        textTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)
        editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)
        textUnit.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)
    }

    val length get() = string.length

    fun isEmpty(): Boolean = string.isEmpty()

    private fun dp(pxValue: Float): Float
    {
        val scale = resources.displayMetrics.density
        return (pxValue + 0.5f) / scale
    }

    private fun resetFilters()
    {
        val filters = ArrayList<InputFilter>()
        if (maxLenFilter != null)
        {
            filters.add(maxLenFilter!!)
        }
        if (limitFilter != null)
        {
            filters.add(limitFilter!!)
        }
        editText.filters = filters.toTypedArray()
    }

    /** 监听输入变化 */
    fun addTextAfterListener(callBack: (s: String) -> Unit)
    {
        editText.addTextChangedListener(object : TextWatcher
        {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int)
            {
            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int)
            {
            }

            override fun afterTextChanged(s: Editable)
            {
                callBack(s.toString())
            }
        })
    }

    fun setOnEditorActionListener(on: TextView.OnEditorActionListener)
    {
        editText.setOnEditorActionListener(on)
    }

    fun setTextListener(initText: CharSequence? = null, onText: (s: String) -> Unit)
    {
        editText.setTextListener(initText, onText)
    }

    fun putText(s: String)
    {
        editText.setText(s)
        editText.setSelection(s.length)
    }

    val textTitleView get() = textTitle
    val editTextView get() = editText
    val textUnitView get() = textUnit
}